/**
 * 
 */
package model.facade.persistence.mysql;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import model.core.torneo.Gara;
import model.core.torneo.Torneo;
import model.core.utente.Giocatore;
import model.core.utente.GiocatoreInterface;
import model.core.utente.Squadra;
import model.core.utente.Studente;
import model.facade.persistence.GaraDAO;

/**
 * @author Giuseppe Fusco (fusgius19@gmail.com)
 *
 */
public class GaraDAO_MySQL extends MySQLDomainDAO implements GaraDAO{

	/**
	 * @param dbms
	 * @throws SQLException 
	 */
	public GaraDAO_MySQL(MySQLDBMS dbms) throws SQLException {
		super(dbms);
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#insert(java.lang.Object)
	 */
	@Override
	public boolean insert(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Gara){
			try {
				synchronized (obj) {
					Gara g = (Gara)obj;
					PreparedStatement p = mys.getPreparedStatement("insert into gara(nome,nro_giorni_da_disputare,data_inizio,data_fine,is_sync,stato_gara,vincitore) values(?,?,?,?,?,?,?)");
					p.setString(1, g.getNome());
					p.setInt(2, g.getNro_giorni_da_disputare());
					p.setTimestamp(3, new Timestamp(g.getData_inizio().getTimeInMillis()));
					p.setTimestamp(4, new Timestamp(g.getData_fine().getTimeInMillis()));
					p.setInt(5, g.isSync()?1:0);
					p.setString(6, g.getStato());
					int idvin = MySQLUtentiQueryUtility.getIdGiocatore(g.getVincitore(), mys);
					if(idvin!=-1)p.setInt(7, idvin);
					else p.setNull(7, Types.NULL);
					p.execute();
					p.close();
					for(GiocatoreInterface gi: g.getGiocatori())
						addPartecipanteToGara(gi, g);
					return true;	
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				return false;
			}
		}else
			return false;
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#delete(java.lang.Object)
	 */
	@Override
	public boolean delete(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Gara){
			Gara g = (Gara)obj;
			try {
				mys.executeUpdate("delete from gara where nome=\""+g.getNome()+"\"");
				return true;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		}else return false;
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#update(java.lang.Object)
	 */
	@Override
	public boolean update(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Gara){
			try {
				synchronized (obj) {
					Gara g = (Gara)obj;
					ResultSet r = mys.getResult("select * from gara where nome=\""+g.getNome()+"\"");
					if(r.first()){
						r.updateString("stato_gara", g.getStato());
						int idvin = MySQLUtentiQueryUtility.getIdGiocatore(g.getVincitore(), mys);
						if(idvin!=-1)r.updateInt("vincitore", idvin);
						else r.updateNull("vincitore");
						r.updateInt("is_sync", g.isSync()?1:0);
						r.updateDate("data_inizio", new Date(g.getData_inizio().getTimeInMillis()));
						r.updateDate("data_fine", new Date(g.getData_fine().getTimeInMillis()));
						r.updateInt("nro_giorni_da_disputare", g.getNro_giorni_da_disputare());
						r.updateRow();
						r.close();
						return true;
					}else
						return false;	
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				return false;
			}
		}else
			return false;
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#retrieve(java.lang.Object[])
	 */
	@Override
	public Object retrieve(Object... properties) {
		// TODO Auto-generated method stub
		if(properties.length==1 && properties[0] instanceof String){
			Gara g = MySQLTorneiQueryUtility.getGaraByNome((String) properties[0], mys);
			g.setGiocatori(getPartecipantiToGara(g));
			return g;
		}else
			return null;
	}
	
	public void addGaraToCalendario(Gara gara, Studente arbitro, Torneo torneo) throws SQLException{
		mys.executeUpdate("insert into calendario(torneo, gara, arbitro) values("+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys)+","+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys)+","+MySQLUtentiQueryUtility.getIdStudente(arbitro.getMatricola(), arbitro.getPassword(), mys)+")");
	}

	public void removeGaraFromCalendario(Gara gara, Torneo torneo) throws SQLException{
		mys.executeUpdate("delete from calendario where gara="+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys)+" and torneo="+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys));
	}
	
	public void addGaraToCalendario(Gara gara, Torneo torneo) throws SQLException{
		mys.executeUpdate("insert into calendario(torneo, gara) values("+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys)+","+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys)+")");
	}

	public void addArbitroToGara(Studente arbitro, Gara gara) throws SQLException{
		mys.executeUpdate("update calendario set arbitro ="+MySQLUtentiQueryUtility.getIdStudente(arbitro.getMatricola(), arbitro.getPassword(), mys)+" where (gara="+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys));
	}

	public void removeArbitroFromGara(Studente arbitro, Gara gara) throws SQLException{
		mys.executeUpdate("update calendario set arbitro =null where gara="+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys));
	}

	public void addPartecipanteToGara(GiocatoreInterface g, Gara gara) throws SQLException{
		mys.executeUpdate("insert into partecipanti_gara(gara,giocatore) values("+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys)+","+(
				(g instanceof Giocatore)?
						MySQLUtentiQueryUtility.getIdGiocatorebyIdStudente((Giocatore)g, mys):
							MySQLUtentiQueryUtility.getIdSquadraByNome(((Squadra)g).getNome(), mys)
				)+")");
	}

	public void removePartecipanteFromGara(GiocatoreInterface g, Gara gara) throws SQLException{
		mys.executeUpdate("delete from partecipanti_gara where (gara="+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys)+" and giocatore="+(
				(g instanceof Giocatore)?
						MySQLUtentiQueryUtility.getIdGiocatorebyIdStudente((Giocatore)g, mys):
							MySQLUtentiQueryUtility.getIdSquadraByNome(((Squadra)g).getNome(), mys)
				)+")");
	}

	public ArrayList<GiocatoreInterface> getPartecipantiToGara(Gara gara){
		ArrayList<GiocatoreInterface> g = new ArrayList<GiocatoreInterface>();
		try {
			ResultSet r = mys.getResult("select * from partecipanti_gara where gara="+MySQLTorneiQueryUtility.getIdGaraByNome(gara.getNome(), mys));
			while(r.next()){
				g.add(MySQLUtentiQueryUtility.getGiocatoreByIdGiocatore(r.getInt("giocatore"), mys));
			}
			return g;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			return g;
		}
	}

	public List<Gara> load(String text) throws SQLException{
		List<Gara> list = new ArrayList<Gara>();
		ResultSet r = mys.getResult("select * from gara where (nome like\"%"+text+"%\" or nro_giorni_da_disputare like\"%"+text+"%\" or " +
				"data_inizio like\"%"+text+"%\" or data_fine like\"%"+text+"%\" or stato_gara like\"%"+text+"%\")");
		while(r.next()){
			list.add((Gara) retrieve(r.getString("nome")));
		}
		r.close();
		return list;
	}
}
